01-31-24 (Wednesday)

Reading from Lectionary, Malachi 3:1-4

1 Built-in types

  • Object types are the ways we have to represent information in our programming.
  • Python has some built-in types we have already seen, but now we will see more.

Some of them are:

  • Numeric types: int, float, complex
  • Boolean types (logic): bool (True and False)
  • Sequence types: list, tuple, str, range, bytes, and others
  • Mapping type: dict
  • Set types: set, frozenset

It is always useful to consult documentation on each to see what you can and can’t do with them.

1.1 Container types

  • Some of these stand for objects that are collection of other objects. These are called containers.
  • For example, you may have a variable pointing to a single number (a numeric type). But you can also a variable pointing to a collection of numbers, or strings, or even other collections of numbers.
  • Think like “drawers” or “boxes” in a bookshelf

1.2 Subscriptable types

  • Remember our metaphor: objects are buildings, variables are addresses
    • As we have types of houses (residential, commercial), we also have types of objects (integer, float, string)
  • How is an address when we have a condo or apartment building - i.e., multiple “houses” in the same address?
    • “1234 Smith Ave Apt 101
  • It is also possible to have containers whose contents can be accessed by some “complement”. These are called subscripts.
    • To access a value, we write the variable followed by some value inside square brackets []

For example, a Python list:

condo = ["room 1", "room 2", "room 3"]
print(condo[0])
room 1

Notice that if we try to “subscript” an object which is not subscriptable, we get an error:

house = 3
print(house[0])
TypeError: 'int' object is not subscriptable

1.3 Sequence vs mapping types

  • In sequence types such as lists, tuples and strings, subscripts are integer numbers, which are called indexes.
    • Attention: indexes always starts at zero!
    • index 0 is for 1st element, index 1 is for 2nd, and so on…
condo = "room 1", "room 2", "room 3"
print(condo[0])
print(condo[1])
print(condo[2])
room 1
room 2
room 3
  • If the index can’t be found, we will have an error:
condo = "room 1", "room 2", "room 3"
print(condo[4])
IndexError: tuple index out of range
  • In mapping types, however, subscripts can be any kind of object (given that it is an immutable object — e.g., lists are not allowed), which are called, in this case, keys.
  • This is the case of the dictionary type (dict):
band = {"vocals": "John Anderson", "guitar":"Steve Howe", "bass": "Chris Squire", "keyboard": "Rick Wakeman"}
print(band["vocals"])
print(band["guitar"])
John Anderson
Steve Howe

1.4 Type properties

  • Subscriptable types: containers whose objects can be accessed using square brackets [];
  • Ordered types: containers whose elements are ordered and thus can be accessed by an index (integer number);
  • Immutable types: objects whose elements cannot be changed;
  • Callable types: functions and classes (check, for example, type(print) or type(math.cos))
    • You “call” these objects to execute some code by typing the object followed by parenthesis (and eventually pass some information inside the parenthesis): print("hi")
    • See what happens if you try calling a non-callable object:
a = 1
a()
TypeError: 'int' object is not callable

Testing some syntax…

a = 1
a[0]
TypeError: 'int' object is not subscriptable
a = 1
a(0)
TypeError: 'int' object is not callable
a = 1
a{0}
SyntaxError: invalid syntax (2290390298.py, line 2)

1.5 Summarizing properties

Type Container Subscriptable Ordered (sequence) Mutable
Numbers and booleans No No No No
Lists Yes Yes (integers) Yes Yes
Tuples Yes Yes (integers) Yes No
Strings Yes (only characters) Yes (integers) Yes No
Dictionaries Yes Yes (immutable objects) No Yes
Sets Yes (only immutable objects) No No Yes

2 Object methods

  • Some objects also have some built-in methods that can be called to perform various operations…
  • To do that, you type the object or the variable which is pointing to it, add a ‘`.``’, and then type the method.

For example, to find the index of an element of a list:

a = ["you", "shall", "not", "pass"]
inot = a.index("not")
print("index of the word 'not' is ",inot)
index of the word 'not' is  2

2.1 Sequence methods

Remember: sequences are ordered and subscriptable with integers (the indexes). The methods below thus work for all of these types: lists, tuples and strings.

Operation Result
x in s True if an item of s is equal to x, else False
x not in s False if an item of s is equal to x, else True
s + t the concatenation of s and t
s * n or n * s equivalent to adding s to itself n times
s[i] ith item of s, origin 0
s[i:j] slice of s from i to j
s[i:j:k] slice of s from i to j with step k
len(s) length of s
min(s) smallest item of s
max(s) largest item of s
s.index(x[, i[, j]]) index of the first occurrence of x in s (at or after index i and before index j)
s.count(x) total number of occurrences of x in s

2.2 Unpacking sequences

All sequence types can also be unpacked in multiple variables. For example:

s = ["I", "am", "your", "father"]
a, b, c, d = s
print(a)
print(b)
I
am
s = "hi!"
ch1, ch2, ch3 = s
print(ch1, ch2, ch3)
h i !

But careful: you will get an error if you don’t match the length:

a = [1, 2, 3]
v1, v2, v3, v4 = a
ValueError: not enough values to unpack (expected 4, got 3)

3 Lists

Mutable sequences, represented as values separated with commas and enclosed with square brackets [].

  • It is possible to initialize an empty list with x = []

3.1 What can go in?

  • Lists and tuples can be a collection of items of any type.
x = (1, 3.33333, "hello", True, 4)
  • You can even make tuples of tuples, lists of lists, lists of tuples…
    • For example: a 3x3 matrix - a 3-element list of 3-element lists
mat = [[1,2,3],
      [4,5,6],
      [7,8,9]]
print(mat[0][1]) # accessing value in row 0 and column 1
2

3.2 Changing versus copying

When dealing with mutable objects, it is very important to check if an operation is changing the object or making a copy of it.

For example:

a = [1,2,3]
b = a
a[1] = 5
print(b)
[1, 5, 3]
  • What happened here? Wasn’t b supposed to remain [1,2,3]?

  • a and b are pointing to the same object (the list [1,2,3]). If we change something in a, we change in b and vice-versa.

  • You can check that with the function id(), which finds an unique integer identifier for each object.

print(id(a))
print(id(b))
140040397696704
140040397696704

It is different if we make a copy of the object.

a = [1,2,3]
b = a.copy()
a[1] = 5
print(a)
print(b)
[1, 5, 3]
[1, 2, 3]
  • Look at the different ids: they are different objects, and thus are independent of each other.
print(id(a))
print(id(b))
140040397690560
140040397691008
  • This happens because lists are mutable objects (just as dictionaries, as we’ll see).
    • Mutable objects need to be copied. Immutable objects don’t.

4 Activity: representing information

What data structure would you use to represent the following? Write down and discuss with your colleagues.

  • The first names of all the students in this course

  • An address book entry (name, email, major, …)

  • A person’s ethnicity

  • A coordinate point, e.g., (0, 0)

  • The atomic number of every element in the periodic table

  • A bag with different colored pieces to be drawn randomly? (For example, in a game like [The Quacks of Quedlinburg](https://boardgamegeek.com/boardgame/244521/quacks-quedlinburg)

5 Discusion: value judgements in representations

  • Every representation is a selective portrait of a reality according to certain interests of who represents it. You can depict only certain parts, at certain moments, and with a certain structure.

  • Thus, we can ask: are we encoding reality correctly?

  • Remember our data types characteristics:

    • Numeric, boolean, containers…
    • Immutable / Mutable
    • Ordered / Non-ordered
    • Callable / Non-callable

Programmers are encoders. Everytime we represent some thing with a data structure, we are supposing that this thing is correctly portrayed with this structure.

  • For example, is a list of people’s name something we can “order”? And for what purpose are we doing that?

  • For example, can emotion be represented with a number? A boolean value? A dictionary indicating multiple aspects of an emotion?

Thus, we also need to acknowledge that data can be:

  • imprecise (including: what it can mean for someone may not mean the same thing for another);

  • ambiguous (may mean multiple things depending on the context);

  • not comprehensive enough (or what we call biased - it is limited to some specific population or situation and thus is not generalizable);

  • distorted (“artifacts” - we cannot always be sure it is being transmitted or recorded faithfully);

  • or even not timely enough (things changed since we got them).

This happens because we limited, situated and always see things from our perspective. This is not bad, however, we need to acknowledge this limitedness. We are not possessors of an all-encompassing truth.

“Through the confusion of tongues, through non-communication, God prevents man from constructing [for himself] a truth valid for all men. In this way, man’s truth will always be partial and contestable” (Jacques Ellul, The Meaning of the City, p. 19).

6 Activity: give examples of cases above:

  • imprecise information:
  • ambiguous information:
  • not comprhensive information:
  • distorted information:
  • non-timely information:

7 Encoding: ruling with justice

  • Remember the origin of the word code: a corpus of law;

  • When we encode things, we are setting a rule;

  • Thus, we are reflecting our kingly vocation as human beings;

  • The Bible talks a lot about JUSTICE as the virtue of a king.

  • To encode correctly, we need to see correctly. And to see correctly, we need a fundamental orientation of heart towards God and his wisdom.

For the Lord grants wisdom! From his mouth come knowledge and understanding. He grants a treasure of common sense to the honest. He is a shield to those who walk with integrity. He guards the paths of the just and protects those who are faithful to him. Then you will understand what is right, just, and fair, and you will find the right way to go. Proverbs 2.6-10

  • We also need a broad knowledge base: “[In ICT design,] one needs to have as broad a knowledge base as possible. It is the outer parameters that one must have knowledge about.” (Jacob and Ebrahimpur 2001, 78)
    • Sociologist Harry Collins calls that interactional expertise - you are not an expert practitioner in the area, but you are informed enough to talk meaninfully with its practicioners.